package com.example.bbs.ui.fragment;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.bbs.R;
import com.example.bbs.base.Data;
import com.example.bbs.bean.Post;
import com.example.bbs.bean.PostQueryParams;
import com.example.bbs.config.HttpConstant;
import com.example.bbs.ui.activity.DisplayActivity;
import com.example.bbs.ui.activity.EditActivity;
import com.example.bbs.util.HttpUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

// TODO(Mid): 显示作者，至少应该显示作者姓名
public class PostBrowseFragment extends BaseTabViewPageFragment implements View.OnClickListener{

    public static class PostBrowseManager implements BrowseFragment.BrowseManager<Post>{

        List<Post> mPostList = new ArrayList<>();
        PostQueryParams mQueryArgsNow = new PostQueryParams();

        @Override
        public int getItemCount() {
            return mPostList.size();
        }

        @Override
        public Post getItem(int pos) {
            if (getItemCount() <= pos) {
                Log.w(LOG_TAG, "post browse index out of range");
                CompletableFuture.runAsync(this::load);
            }
            if (getItemCount() > pos) {
                return mPostList.get(pos);
            }
            return null;
        }

        @Override
        public int load() {
            String strJson = JSON.toJSONString(mQueryArgsNow.nextPage());
            Log.d(LOG_TAG, "load start: " + strJson);
            JSONObject json = HttpUtil.post(HttpConstant.REQUEST_QUERY_POST, strJson);
            if (json == null)
                return 0;
            JSONArray result = json.getJSONArray(HttpConstant.FIELD_DATA);
            if (result.size() == 0)
                return 0;
            int previousSize = mPostList.size();
            for (int i = 0; i < result.size(); i++) {
                Post newPost = result.getObject(i, Post.class);
                mPostList.add(newPost);
            }
            Log.d(LOG_TAG, "load success: " + mPostList.size());
            return mPostList.size() - previousSize;
        }

        @Override
        public void reset() {
            mPostList.clear();
            mQueryArgsNow.setPage(0);
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        Post post;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            itemView.setOnClickListener((v) -> {
                Intent intent = new Intent(getContext(), DisplayActivity.class);
                intent.putExtra(DisplayActivity.INTENT_EXTRA_POST, post);
                startActivity(intent);
            });
        }

        public void setPost(Post post) {
            this.post = post;

            TextView titleTextView = itemView.findViewById(R.id.tv_item_title);
            titleTextView.setText(post.getTitle());
            TextView contentTextView = itemView.findViewById(R.id.tv_item_content);
            contentTextView.setText(post.getAbstractContent());
        }
    }

    public class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = View.inflate(parent.getContext(), R.layout.view_item_post_browse, null);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            ((ViewHolder)holder).setPost(postBrowseManager.getItem(position));
        }

        @Override
        public int getItemCount() {
            return postBrowseManager.getItemCount();
        }
    }

    static final String LOG_TAG = PostBrowseFragment.class.getSimpleName();

    ImageView btnAdd;
    TextView tvStyleAll;
    TextView tvStyleText;
    TextView tvStyleImage;
    TextView tvStyleAudio;
    TextView tvStyleVideo;
    TextView tvOrderDefault;
    TextView tvOrderTime;
    TextView tvOrderLike;
    BrowseFragment browseFragment;
    PostBrowseManager postBrowseManager = new PostBrowseManager();

    public static PostBrowseFragment newInstance(boolean favoriteOnly) {
        PostBrowseFragment fragment =  new PostBrowseFragment();
        fragment.getQueryParams().setFavoriteOnly(favoriteOnly);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_post_browse, container, false);
        initView(rootView);
        initClickListener();

        return rootView;
    }

    public void initView(View v) {
        btnAdd = v.findViewById(R.id.btn_add);
        tvStyleAll = v.findViewById(R.id.tv_style_all);
        tvStyleText = v.findViewById(R.id.tv_style_text);
        tvStyleImage = v.findViewById(R.id.tv_style_image);
        tvStyleAudio = v.findViewById(R.id.tv_style_audio);
        tvStyleVideo = v.findViewById(R.id.tv_style_video);
        tvOrderDefault = v.findViewById(R.id.tv_order_default);
        tvOrderTime = v.findViewById(R.id.tv_order_time);
        tvOrderLike = v.findViewById(R.id.tv_order_like);

        // 默认选项
        for (TextView textView : new TextView[] { tvStyleAll, tvStyleText, tvStyleImage,
                tvStyleAudio, tvStyleVideo, tvOrderDefault }) {
            PostBrowseFragment.setBinaryButton(getContext(), textView, true);
        }
        getQueryParams().setOrder(PostQueryParams.ORDER_DEFAULT);
    }

    private void initClickListener() {
        btnAdd.setOnClickListener(this);
        tvStyleAll.setOnClickListener(this);
        tvStyleText.setOnClickListener(this);
        tvStyleImage.setOnClickListener(this);
        tvStyleAudio.setOnClickListener(this);
        tvStyleVideo.setOnClickListener(this);
        tvOrderDefault.setOnClickListener(this);
        tvOrderTime.setOnClickListener(this);
        tvOrderLike.setOnClickListener(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(LOG_TAG, "onResume");

        getQueryParams().setKeywords(new String[]{});
        postBrowseManager.reset();

        Adapter adapter = new Adapter();
        browseFragment = BrowseFragment.newInstance(postBrowseManager, adapter);
        getChildFragmentManager().beginTransaction()
                .add(R.id.fcv_post_browse, browseFragment)
                .commit();
    }

    @Override
    public void onPause() {
        getChildFragmentManager().beginTransaction()
                .remove(browseFragment)
                .commit();

        super.onPause();
        Log.d(LOG_TAG, "onPause");
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();

        if (id == R.id.btn_add) {
            Intent intent = new Intent();
            intent.setClass(requireContext(), EditActivity.class);
            startActivity(intent, new Bundle());

        } else if (id == R.id.tv_style_all) {
            boolean state = !tvStyleAll.isSelected();
            for (TextView textView : new TextView[] { tvStyleAll, tvStyleText, tvStyleImage, tvStyleAudio, tvStyleVideo }) {
                setBinaryButton(getContext(), textView, state);
            }
            setStyle(Post.STYLE_ALL, view.isSelected());
            reset();

        } else if (id == R.id.tv_style_text) {
            setBinaryButton(getContext(), (TextView) view, !view.isSelected());
            setStyle(Post.STYLE_TEXT_ONLY, view.isSelected());
            reset();

        } else if (id == R.id.tv_style_image) {
            setBinaryButton(getContext(), (TextView) view, !view.isSelected());
            setStyle(Post.STYLE_IMAGE, view.isSelected());
            reset();

        } else if (id == R.id.tv_style_audio) {
            setBinaryButton(getContext(), (TextView) view, !view.isSelected());
            setStyle(Post.STYLE_AUDIO, view.isSelected());
            reset();

        } else if (id == R.id.tv_style_video) {
            setBinaryButton(getContext(), (TextView) view, !view.isSelected());
            setStyle(Post.STYLE_VIDEO, view.isSelected());
            reset();

        } else if (id == R.id.tv_order_default) {
            setOrderRadioButton(view);
            getQueryParams().setOrder(PostQueryParams.ORDER_DEFAULT);
            reset();

        } else if (id == R.id.tv_order_time) {
            setOrderRadioButton(view);
            getQueryParams().setOrder(PostQueryParams.ORDER_TIME);
            reset();

        } else if (id == R.id.tv_order_like) {
            setOrderRadioButton(view);
            getQueryParams().setOrder(PostQueryParams.ORDER_LIKE);
            reset();

        }
    }

    public static void setBinaryButton(Context context, TextView textView, boolean selected) {
        if (selected) {
            textView.setBackgroundResource(R.drawable.border_color_theme_round_3);
            textView.setTextColor(context.getColor(R.color.primary));
        } else {
            textView.setBackgroundResource(R.drawable.border_round_3);
            textView.setTextColor(context.getColor(R.color.light_grey));
        }
        textView.setSelected(selected);
    }

    public void setStyle(int mask, boolean value) {
        if (value)
            getQueryParams().setStyle(getQueryParams().getStyle() | mask);
        else
            getQueryParams().setStyle(getQueryParams().getStyle() & ~mask);
    }

    // 这里应该使用 radioButton，因为格式一致和一些历史原因，写成 textView。暂时不改。
    public void setOrderRadioButton(View v) {
        TextView oldTextView = null;
        switch (getQueryParams().getOrder()) {
            case PostQueryParams.ORDER_DEFAULT:
                oldTextView = tvOrderDefault; break;
            case PostQueryParams.ORDER_TIME:
                oldTextView = tvOrderTime; break;
            case PostQueryParams.ORDER_LIKE:
                oldTextView = tvOrderLike; break;
        }
        if (v.isSelected() || getContext() == null || oldTextView == null)
            return;
        oldTextView.setBackgroundResource(R.drawable.border_round_3);
        oldTextView.setTextColor(getContext().getColor(R.color.light_grey));
        oldTextView.setSelected(false);
        v.setBackgroundResource(R.drawable.border_color_theme_round_3);
        ((TextView) v).setTextColor(getContext().getColor(R.color.primary));
        v.setSelected(true);
    }

    @Override
    public String getName() {
        return Data.context.getString(getQueryParams().isFavoriteOnly() ? R.string.t_care : R.string.t_browse);
    }

    public void reset() {
        postBrowseManager.reset();
        CompletableFuture.runAsync(() -> postBrowseManager.load())
                .thenRun(() -> requireActivity().runOnUiThread(() -> browseFragment.reset()));
    }

    public PostQueryParams getQueryParams() {
        return postBrowseManager.mQueryArgsNow;
    }
}